package cloudspace.vm.javassist;

import java.util.List;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.expr.Expr;

import org.apache.log4j.Logger;

import cloudspace.vm.VM;
import cloudspace.vm.javassist.AbstractCommand.SignatureType;


/**
 * This is a command to add a field to a given class. Configuration files for
 * this class are specified as follows.
 * 
 * translate AddField <Class Name> <Field Type> <Name>
 * 
 * The class name specifies the name of the class to add the field to. Class
 * name can be a super type as well (in case you want to broaden the type of
 * class you want to add the field to). The field type is the type that the
 * field should be defined as. The name of the class will be the declared name
 * of the class.
 * 
 * @author mike
 * 
 */
public class AddField implements CommandInterface
{
    private List<String> configArgs;

    private Logger logger = Logger.getLogger( AddField.class );


    /**
     * generic constructor to create a new command.
     * 
     * @param arguments
     */
    public AddField( List<String> args )
    {
        configArgs = args;
    }


    public String getReplacement()
    {
        return configArgs.get( 4 ).substring( 1,
            configArgs.get( 4 ).length() - 1 );
    }


    public String getSignature()
    {
        return configArgs.get( 1 );
    }


    public SignatureType getSignatureType()
    {
        return SignatureType.STATICDEFINITION;
    }


    public void translate( Expr call, boolean isSuper )
        throws MalformedCommandException,
        CannotCompileException
    {
        throw new MalformedCommandException( "This command is not implemented" );

    }


    public void translate( CtMethod member, String expressionName )
        throws MalformedCommandException,
        CannotCompileException,
        MalformedCommandException
    {
        throw new MalformedCommandException( "This command is not implemented" );

    }


    public void translate( CtClass clazz )
        throws MalformedCommandException,
        CannotCompileException
    {

        try
        {
            CtClass superClazz = clazz.getSuperclass();
            while ( superClazz != null )
            {
                if ( superClazz.getName().equals( getSignature() ) )
                {
                    CtClass clazz2;
                    clazz2 = VM.currentVM()
                        .getClassPool()
                        .get( configArgs.get( 2 ) );
                    CtField field = new CtField( clazz2,
                        configArgs.get( 3 ),
                        clazz );
                    CtNewMethod.setter( "set" + configArgs.get( 3 ), field );
                    CtNewMethod.getter( "get" + configArgs.get( 3 ), field );
                    clazz.addField( field, getReplacement() );
                }
                superClazz = superClazz.getSuperclass();
            }
        }
        catch ( NotFoundException e )
        {
            logger.error( "Class Not Found:  " + clazz.getName(), e );
        }

    }

}
